package com.fulihui.usercore.core.processor.auth;

import com.fulihui.usercore.biz.shard.WechatUserManager;
import com.fulihui.usercore.common.util.AppProps;
import com.fulihui.usercore.core.repository.WechatUnionidHelpRepository;
import com.fulihui.usercore.core.repository.WechatUserRepository;
import com.fulihui.usercore.dal.dataobj.WechatUnionidHelpDOExample;
import com.fulihui.usercore.dto.UserDTO;
import com.fulihui.usercore.dto.WechatUserDTO;
import com.fulihui.usercore.enums.*;
import com.fulihui.usercore.request.auth.AbstractAuthRequest;
import com.fulihui.usercore.request.auth.WechatAuthRequest;
import com.fulihui.usercore.sdk.domain.SignTypeEnum;
import org.near.servicesupport.error.CommonServiceErrorEnum;
import org.near.servicesupport.error.InvokeServiceException;
import org.near.toolkit.common.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static java.util.Collections.singletonList;

/**
 *
 * @author: Levon
 * @version: v 0.1 2017-07-20 17:21
 */
@Component("weiXinLoginAuthProcessor")
public class WeiXinLoginAuthProcessor extends AbstractAuthProcessor {

    @Autowired
    private WechatUserRepository wechatUserRepository;
    @Autowired
    private AppProps appProps;
    @Autowired
    private TransactionTemplate transactionTemplate;
    @Autowired
    private WechatUserManager wechatUserManager;
    @Autowired
    private WechatUnionidHelpRepository wechatUnionidHelpRepository;

    /**
     * 登录流程
     *
     * @param request {@link AbstractAuthRequest}
     * @return userid
     */
    @Override
    public String login(AbstractAuthRequest request) {
        String userId = "";
        WechatAuthRequest wechatAuthRequest = (WechatAuthRequest) request;
        String defaultAppid = appProps.getWechatMpAppid();
        if (!StringUtil.equals(WechatOpenIdTypeEnum.WECHAT_MP.getCode(),wechatAuthRequest.getOpenidType())) {
            throw new InvokeServiceException(CommonServiceErrorEnum.REQUEST_PARAMETER_ERROR);
        }
        if (StringUtil.isBlank(wechatAuthRequest.getAppid())) {
            wechatAuthRequest.setAppid(defaultAppid);
        }
        WechatUnionidHelpDOExample example = new WechatUnionidHelpDOExample();
        example.createCriteria().andUnionidEqualTo(wechatAuthRequest.getUnionid());
        List<WechatUserDTO> wechatUserDTOList = wechatUnionidHelpRepository.query(example);
        if(CollectionUtils.isEmpty(wechatUserDTOList)){
            userId = transactionTemplate.execute(status -> {
                String _userid= super.register(request);
                //绑定微信
                WechatUserDTO wechatUserDTONew = this.buildWechatUserDTO(_userid, wechatAuthRequest);
                wechatUserManager.bindingByUserId(wechatUserDTONew);
                return _userid;
            });
        }else{
            boolean isBindingWechat = false;
            for (WechatUserDTO wechatUserDTO : wechatUserDTOList) {
                if (StringUtil.equals(WechatOpenIdTypeEnum.WECHAT_MP.getCode(),wechatUserDTO.getOpenidType())){
                    //已绑定微信
                    isBindingWechat =true;
                    userId = wechatUserDTO.getUserId();
                    break;
                }
            }
            if (!isBindingWechat){
                userId = wechatUserDTOList.get(0).getUserId();
                //资讯已经绑定，微信未绑定
                //绑定微信
                WechatUserDTO wechatUserDTONew = this.buildWechatUserDTO(userId, wechatAuthRequest);
                wechatUserManager.bindingByUserId(wechatUserDTONew);

            }
            checkLoginUserState(userId); //检查用户是否被拉黑
            signPublish(request, userId, SignTypeEnum.SIGN_IN);//登入发布订阅消息
            asyncSignInExecute(userId, request);//记录登录状态
        }
        return userId;
    }
    /**
     * 组装绑定微信dto
     * @param userId
     * @param request
     * @return
     */
    private WechatUserDTO buildWechatUserDTO(String userId,WechatAuthRequest request){
        WechatUserDTO record = new WechatUserDTO();
        record.setOpenId(request.getOpenid());
        record.setOpenidType(request.getOpenidType());
        record.setUnionid(request.getUnionid());
        record.setUserId(userId);
        return record;
    }


    @Override
    protected void registerCheck(AbstractAuthRequest request) {

    }
    /**
     * 授权类型
     *
     * @return {@link UserRegisterTypeEnum}
     */
    @Override
    public String authType() {
        return UserRegisterTypeEnum.WEIXIN_AUTH.getCode();
    }

    /**
     * 通过请求参数生成用户模型
     *
     * @param request {@link AbstractAuthRequest} 的子类
     * @return {@link UserDTO}
     */
    @Override
    UserDTO toUserModel(AbstractAuthRequest request) {
        WechatAuthRequest wechatAuthRequest = (WechatAuthRequest) request;
        UserDTO userDTO = new UserDTO();
        userDTO.setRegisterType(authType());
        userDTO.setRegisterSource(request.getRegisterSource());
        if (wechatAuthRequest.getSex() == 1) {
            userDTO.setGender(UserGenderEnum.MEN.getCode());
        } else if (wechatAuthRequest.getSex() == 2) {
            userDTO.setGender(UserGenderEnum.WOMEN.getCode());
        } else {
            userDTO.setGender(UserGenderEnum.UNKNOW.getCode());
        }
        if (StringUtil.isNotBlank(wechatAuthRequest.getNickname())) {
            userDTO.setNickname(StringUtil.filterEmoji(wechatAuthRequest.getNickname()));
            userDTO.setMemo(nicknameGenerator.generate());
        } else {
            String nickname = nicknameGenerator.generate();
            userDTO.setNickname(nickname);
            userDTO.setMemo(nickname);
        }
        // XXX 目前微信登入没有手机号
        userDTO.setMobileNo(request.getLoginId());
        userDTO.setMobileVerified(BooleanValueEnum.FALSE.isTrue());

        userDTO.setHeadImg(wechatAuthRequest.getHeadImg());
        userDTO.setState(UserStateEnum.NOMAL.getCode());
        userDTO.setRoleCode("USER_NOMAL");
        userDTO.setProvince(wechatAuthRequest.getWxProvince());
        userDTO.setCity(wechatAuthRequest.getWxCity());
        Date now = new Date();
        userDTO.gmtCreate(now);
        userDTO.lastLogin(now);
        userDTO.setErduoVersion(request.getErduoVersion());

        if (request.getUsedProduct() != null) {
            userDTO.setUsedProducts(singletonList(request.getUsedProduct()));
        }

        Map<String, Object> param = new HashMap<>();
        if (StringUtil.isNotBlank(request.getUserIP())) {
            param.put("userIp", request.getUserIP());
        }
        if (param.size() > 0) {
            userDTO.setExtInfo(param);
        }
        return userDTO;
    }
}
